﻿
//语法分析器
//输入: 词组序列 --> 语法分隔树
//输出格式:
//#0 @源程序 #1 @函数组1 0 1 2 3 ... #1 #15 @函数组2 34 35 36 ... #15 #0
namespace n_PyParseNet
{
using System;
using n_PyET;
using n_PyParseNet_inside;
using n_PyWordList;
using System.Text;
using i_Compiler;
using n_OS;

public static class ParseNet
{
	//节点常量类
	public static class Node
	{
		//=======================================================================
		public const string 源程序 = "@源程序";// --> #顺序 @元件 *结束<<<<
		//=======================================================================
		public const string 顶层元素列表 = "@顶层元素列表";// --> #重复 @成员<<<<
		public const string 顶层元素 = "@顶层元素";
		//=======================================================================
		public const string 成员列表 = "@成员列表";// --> #重复 @成员<<<<
		public const string 成员 = "@成员";
		//------------------------------
		public const string 元件 = "@元件";// --> #顺序 ?@重命名项 @成员类型 unit @标识符 { @成员列表 } ?@连接目标<<<<
		//------------------------------
		public const string 常量 = "@常量";// --> #顺序 @成员类型 @变量类型 @标识符 = @变量定义数字前缀 @名称 ;<<<<
		//------------------------------
		public const string 静态变量 = "@静态变量";// --> #顺序 @成员类型 @变量类型 @全局变量分隔 ;<<<<
		public const string 地址常量 = "@地址常量";// --> #或 @静态变量引用 @立即数地址 @数组 @名称<<<<
		public const string 立即数地址 = "@立即数地址";// --> #顺序 [ u . addr ] @名称<<<<
		public const string 静态变量引用 = "@静态变量引用";// --> #顺序 @成员引用 ?@静态变量引用后缀<<<<
		public const string 数组 = "@数组";// --> #顺序 { @数组元素列表 }<<<<
		public const string 数组元素列表 = "@数组元素列表";// --> #分隔 , @名称<<<<
		public const string 静态变量引用后缀 = "@静态变量引用后缀";// --> #顺序 . @名称 ?@静态变量引用修饰<<<<
		public const string 静态变量引用修饰 = "@静态变量引用修饰";// --> #顺序 [ @基本变量类型 ]<<<<
		//------------------------------
		public const string 函数 = "@函数";
		public const string 形参 = "@形参";
		public const string 快速结束 = "@快速结束";
		public const string 接口调用 = "@接口调用";
		public const string 中断 = "@中断";
		//------------------------------
		public const string 结构体定义 = "@结构体定义";// --> #顺序 @成员类型 struct @标识符 { @结构体成员列表 } ?@连接目标<<<<
		//------------------------------
		public const string 虚拟数据定义 = "@虚拟数据定义";// --> #顺序 @成员类型 vdata @标识符 { @虚拟数据属性列表 } ?@连接目标<<<<
		public const string 虚拟数据元件引用 = "@虚拟数据元件引用";// --> #顺序 unit = @成员引用 ;<<<<
		public const string 虚拟数据类型指定 = "@虚拟数据类型指定";// --> #顺序 type = [ @虚拟数据地址 ] @基本变量类型 ;<<<<
		//------------------------------
		public const string 设置属性 = "@设置属性";
		public const string 设置当前包 = "@设置当前包";
		public const string 设置编译参数 = "@设置编译参数";
		public const string 连接器 = "@连接器";
		//=======================================================================
		public const string 语句 = "@语句";// --> #或 @标号语句 @流程语句 @变量定义语句 @表达式语句 @语句块 @控制语句 @内嵌汇编<<<<
		public const string 标号语句 = "@标号语句";// --> #顺序 @标识符 :<<<<
		public const string 表达式语句 = "@表达式语句";
		public const string 复合语句 = "@复合语句";// --> #顺序 { ?@语句列表 }<<<<
		public const string 流程语句 = "@流程语句";// --> #或 @return语句 @break语句 @continue语句 @goto语句<<<<
		public const string 流程控制 = "@流程控制";
		public const string 返回控制 = "@返回控制";
		public const string 异常控制 = "@异常控制";
		public const string 空语句控制 = "@空语句控制";
		public const string 中断控制 = "@中断控制";
		public const string OK = "@OK";
		public const string 跳至开始控制 = "@跳至开始控制";
		public const string 跳至结尾控制 = "@跳至结尾控制";
		public const string 跳至控制 = "@跳至控制";
		public const string 内嵌汇编 = "@内嵌汇编";// --> #顺序 # asm @名称<<<<
		public const string 系统标志 = "@系统标志";
		//public const string 空语句 = "@空语句";
		//=======================================================================
		public const string 控制语句 = "@控制语句";// --> #或 @ifelse语句 @if语句 @do语句 @while语句 @for语句 @loop语句 @switch语句 @forever语句 @once语句<<<<
		public const string 反复执行语句 = "@反复执行语句";
		public const string 单次执行语句 = "@单次执行语句";
		public const string forever语句 = "@forever语句";
		public const string 迭代语句 = "@迭代语句";
		public const string loop语句 = "@loop语句";
		public const string while语句 = "@while语句";
		public const string dowhile语句 = "@dowhile语句";
		public const string 流程初始化 = "@流程初始化";
		public const string 流程附加操作 = "@流程附加操作";
		public const string 流程条件判断 = "@流程条件判断";
		public const string 流程次数判断 = "@流程次数判断";
		public const string 如果语句 = "@如果语句";// --> #顺序 if ( @表达式 ) @语句<<<<
		public const string 如果否则语句 = "@如果否则语句";// --> #顺序 if ( @表达式 ) @语句 else @语句<<<<
		public const string 多分支如果语句 = "@多分支如果语句";
		public const string 分支判断 = "@分支判断";// --> #顺序 @分支转移列表 ?@默认转移<<<<
		public const string 默认转移 = "@默认转移";// --> #顺序 default : @语句列表<<<<
		public const string 分支转移列表 = "@分支转移列表";// --> #重复 @分支转移<<<<
		public const string 分支转移 = "@分支转移";// --> #顺序 case @表达式 : @语句列表<<<<
		//=======================================================================
		public const string 表达式 = "@表达式";// --> #优先分隔 @双目运算符 @操作数<<<<
		public const string 操作数 = "@操作数";// --> #或 @单目运算 @括号运算 @函数调用 @变量<<<<
		public const string 括号运算 = "@括号运算";// --> #顺序 ( @表达式 )<<<<
		public const string 函数地址 = "@函数地址";
		public const string 函数变量尺寸 = "@函数变量尺寸";
		public const string 函数调用 = "@函数调用";
		public const string 实参列表 = "@实参列表";// --> #分隔 , @表达式<<<<
		public const string 变量 = "@变量";// --> #顺序 ?A @名称 @重复后缀<<<<
		public const string 列表定义 = "@列表定义";
		public const string 新变量 = "@新变量";
		public const string 重复后缀 = "@重复后缀";// --> #重复 @点运算<<<<
		public const string 单目运算 = "@单目运算";// --> #顺序 @单目运算符 @操作数<<<<
		public const string 常量数组分量 = "@常量数组分量";
		public const string 单目运算符 = "@单目运算符";// --> #或 ! ~ - + ++ -- @前括号运算<<<<
		public const string 前括号运算 = "@前括号运算";// --> #顺序 ( @前括号运算子 )<<<<
		public const string 前括号运算子 = "@前括号运算子";// --> #或 uint sint @变量类型<<<<
		public const string 点运算 = "@点运算";// --> #顺序 . @分量表达式 ?@点运算修饰<<<<
		public const string 分量表达式 = "@分量表达式";// --> #或 @名称 @括号运算<<<<
		public const string 点运算修饰 = "@点运算修饰";// --> #顺序 [ @基本变量类型 ]<<<<
		public const string 双目运算符 = "@双目运算符";// --> #或 * / % + - & | ^ >> << > < >= <= == != && || ^^ = -> *= /= %= += -= &= |= ^= >>= <<= &&= ||= ^^=<<<<
		//=======================================================================
		public const string 变量类型 = "@变量类型";// --> #顺序 ?@类型前缀列表 @变量或自定义基本类型<<<<
		public const string 变量或自定义基本类型 = "@变量或自定义基本类型";// --> #或 @普通变量基本类型 @结构体类型<<<<
		public const string 普通变量基本类型 = "@普通变量基本类型";// --> #顺序 ?@成员引用 @基本变量类型<<<<
		public const string 结构体名称 = "@结构体名称";// --> #顺序 ?struct @成员引用<<<<
		public const string 结构体类型 = "@结构体类型";
		public const string 数组类型 = "@数组类型";
		public const string 数组大小 = "@数组大小";// --> #或 @成员引用 @名称<<<<
		public const string 引用前缀 = "@引用前缀";// --> #顺序 ?@标识符 &<<<<
		public const string 引用前缀符号 = "@引用前缀符号";// --> #顺序 ?@标识符 &<<<<
		public const string 指针前缀符号 = "@指针前缀符号";// --> #顺序 ?@标识符 &<<<<
		//------------------------------
		public const string 基本变量类型 = "@基本变量类型";// --> #或 uint8 sint8 uint16 sint16 uint24 sint24 uint32 sint32 bit bool float<<<<
		//------------------------------
		public const string 成员访问 = "@成员访问";
		public const string ROOT = "@root";
		//------------------------------
		public const string 成员类型 = "@成员类型";// --> #重复 @成员类型定义<<<<
		public const string 成员类型定义 = "@成员类型定义";// --> #或 private public real link<<<<
		//------------------------------
		public const string 名称 = "@名称";// --> #名称<<<<
		public const string 标识符 = "@标识符";// --> #标识符<<<<
		public const string 问号 = "@问号";// --> @问号<<<<
		
		//系统内部
		public const string 终结词 = "@终结词";// --> #终结词<<<<
	}
	
	//初始化,加载文件
	public static void Init()
	{
		//加载语法树规则集
		LoadFile();
		
		//优先级类初始化
		PRI.Init();
	}
	
	//初始化,加载语法树文件
	static void LoadFile()
	{
		string[] Lines;
		
		string s = Compiler.OpenCompileFile( n_PyConfig.Config.Path_pycompiler + "parse_tree.lst" );
		s = s.Remove( s.IndexOf( "\n<end>" ) );
		Lines = s.Split( '\n' );
		string[] ParseList = new string[ Lines.Length ];
		LinesOfWord = new int[ Lines.Length ];
		int j = 0;
		for( int i = 0; i < Lines.Length; ++i ) {
			if( !Lines[ i ].StartsWith( "//" ) ) {
				LinesOfWord[ j ] = i;
				ParseList[ j ] = Lines[ i ].Remove( Lines[ i ].IndexOf( "<<<<" ) ).TrimStart( ' ' );
				++j;
			}
		}
		ParseCut = new string[ j ][];
		for( int i = 0; i < j; ++i ) {
			ParseCut[ i ] = ParseList[ i ].Split( ' ' );
		}
	}
	
	//显示语法树
	public static string Show()
	{
		StringBuilder Result = new StringBuilder( "" );
		for( int Index = 0; Index < length; ++Index ) {
			Result.Append( Index + ":\t" + string.Join( " ", NodeSet[ Index ] ) + "\n" );
		}
		return Result.ToString();
	}
	
	//测试程序--检查语法树
	public static void Check()
	{
		LoadFile();
		ET.Clear();
		
		string ExistIndexSet = " ";
		for( int Line = 0; Line < ParseCut.Length; ++Line ) {
			
			string[] Cut = ParseCut[ Line ];
			for( int Index = 1; Index < Cut.Length; ++Index ) {
				string Head = Cut[ Index ];
				if( Head == "" ) {
					ET.WriteLineError( 0, LinesOfWord[ Line ], "语法定义中有多余的空格" );
					continue;
				}
				if( Head.StartsWith( "?" ) ) {
					Head = Head.Remove( 0, 1 );
				}
				if( !Head.StartsWith( "@" ) || Head == "@" ) {
					continue;
				}
				
				bool isExist = false;
				for( int i = 0; i < ParseCut.Length; ++i ) {
					if( ParseCut[ i ][ 0 ] == Head ) {
						isExist = true;
						ExistIndexSet += i + " ";
						break;
					}
				}
				if( !isExist ) {
					ET.WriteLineError( 0, LinesOfWord[ Line ], "未定义的词: " + Head );
				}
			}
		}
		for( int i = 0; i < ParseCut.Length; ++i ) {
			if( ExistIndexSet.IndexOf( " " + i + " " ) == -1 ) {
				ET.WriteLineError( 0, LinesOfWord[ i ], "未使用的词: " + ParseCut[ i ][ 0 ] );
			}
		}
	}
	
	//分析源程序的词语序列
	public static void Parse()
	{
		Reset();
		Index = 0;
		FarthestIndex = 0;
		ErrorDescribe = "";
		ReturnMessage r = AssayWord( Node.源程序 );
		if( !r.isRight ) {
			ET.WriteParseError( FarthestIndex, ErrorDescribe );
		}
	}
	
	//重置网络
	static void Reset()
	{
		NodeSet = new string[ WordList.GetLength() * 10 ][];
		for( int i = 0; i < WordList.GetLength(); ++i ) {
			NodeSet[ i ] = new string[ 2 ];
			NodeSet[ i ][ 0 ] = Node.终结词;
			NodeSet[ i ][ 1 ] = WordList.GetWord( i );
		}
		length = WordList.GetLength();
	}
	
	//添加节点
	static int AddNode( string[] Node )
	{
		NodeSet[ length ] = Node;
		++length;
		return length - 1;
	}
	
	//分析一个词--位置:Index  返回描述:Result  返回值:是否分析成功
	//分析成功则Index指向下一个词
	static ReturnMessage AssayWord( string Parse )
	{
		//建立返回值
		ReturnMessage r = new ReturnMessage( false );
		
		//终结词分析
		if( !Parse.StartsWith( "@" ) ) {
			return 终结词( r, Parse );
		}
		string[] Cut = GetParse( Parse );
		switch( Cut[ 2 ] ) {
			case "#名称" :		return 名称( r );
			case "#用户名称" :	return 用户名称( r );
			case "#标识符" :	return 标识符( r );
			case "#顺序" :		return 顺序( r, Cut );
			case "#或" :		return 或( r, Cut );
			case "#重复" :		return 重复( r, Cut );	//允许空项
			case "#多次重复" :	return 多次重复( r, Cut );	//不允许空项
			case "#分隔" :		return 分隔( r, Cut );	//至少1项
			case "#优先分隔" :	return 优先分隔( r, Cut );	//至少1项
			default: 		ET.WriteParseError( Index, "系统错误:未定义的词语--" + Cut[ 0] ); return r;
		}
	}
	
	static ReturnMessage 终结词( ReturnMessage r, string Parse )
	{
		if( WordList.GetWord( Index ) == Parse ) {
			r.isRight = true;
			r.result = Index.ToString();
			++Index;
			return r;
		}
		if( FarthestIndex <= Index ) {
			FarthestIndex = Index;
			ErrorDescribe = "<终结词> 预期词: " + Parse + " 实际词: " + WordList.GetWord( Index );
		}
		return r;
	}
	
	static ReturnMessage 名称( ReturnMessage r )
	{
		if( WordType.isName( WordList.GetWord( Index ) ) ) {
			r.isRight = true;
			r.result = Index.ToString();
			++Index;
			return r;
		}
		if( FarthestIndex <= Index ) {
			FarthestIndex = Index;
			ErrorDescribe = "<名称> 预期名称类型的词, 实际词: " + WordList.GetWord( Index );
		}
		return r;
	}
	
	static ReturnMessage 用户名称( ReturnMessage r )
	{
		if( WordType.isUserName( WordList.GetWord( Index ) ) ) {
			r.isRight = true;
			r.result = Index.ToString();
			++Index;
			return r;
		}
		if( FarthestIndex <= Index ) {
			FarthestIndex = Index;
			ErrorDescribe = "<名称> 预期用户名称类型的词, 实际词: " + WordList.GetWord( Index );
		}
		return r;
	}
	
	static ReturnMessage 标识符( ReturnMessage r )
	{
		if( WordType.isIdentifier( WordList.GetWord( Index ) ) ) {
			r.isRight = true;
			r.result = Index.ToString();
			++Index;
			return r;
		}
		if( FarthestIndex <= Index ) {
			FarthestIndex = Index;
			ErrorDescribe = "<标识符> 预期标识符类型的词, 实际词: " + WordList.GetWord( Index );
		}
		return r;
	}
	
	static ReturnMessage 顺序( ReturnMessage r, string[] Cut )
	{
		int TempIndex = Index;
		int Length = length;
		string result = "";
		for( int i = 3; i < Cut.Length; ++i ) {
			bool EnSure = true;
			string Head =  Cut[ i ];
			if( Head.StartsWith( "?" ) ) {
				Head = Head.Remove( 0, 1 );
				EnSure = false;
			}
			r = AssayWord( Head );
			if( !r.isRight && EnSure ) {
				Index= TempIndex;
				length = Length;
				return r;
			}
			if( r.isRight ) {
				result += r.result + " ";
			}
			else {
				result += "-1 ";
			}
		}
		result = Cut[ 0 ] + " " + result.TrimEnd( ' ' );
		int Name = AddNode( result.Split( ' ' ) );
		r.isRight = true;
		r.result = Name.ToString();
		return r;
	}
	
	static ReturnMessage 或( ReturnMessage r, string[] Cut )
	{
		int TempIndex = Index;
		int Length = length;
		for( int i = 3; i< Cut.Length; ++i ) {
			r = AssayWord( Cut[ i ] );
			if( r.isRight ) {
				return r;
			}
		}
		if( FarthestIndex <= Index ) {
			FarthestIndex = Index;
			ErrorDescribe = "<或> 预期词: " + Cut[ 0 ].Remove( 0, 1 ) + " 实际词: " + WordList.GetWord( Index );
		}
		Index = TempIndex;
		Length = length;
		return r;
	}
	
	static ReturnMessage 重复( ReturnMessage r, string[] Cut )
	{
		string result = "";
		while( true ) {
			r = AssayWord( Cut[ 3 ] );
			if( !r.isRight ) {
				break;
			}
			result += r.result + " ";
		}
		result = Cut[ 0 ] + " " + result.TrimEnd( ' ' );
		result = result.TrimEnd( ' ' );
		int Name = AddNode( result.Split( ' ' ) );
		r.isRight = true;
		r.result = Name.ToString();
		return r;
	}
	
	static ReturnMessage 多次重复( ReturnMessage r, string[] Cut )
	{
		int TempIndex = Index;
		int TempLength = length;
		bool isExist = false;
		string result = "";
		while( true ) {
			r = AssayWord( Cut[ 3 ] );
			if( !r.isRight ) {
				break;
			}
			result += r.result + " ";
			isExist = true;
		}
		if( !isExist ) {
			Index = TempIndex;
			length = TempLength;
			return r;
		}
		result = Cut[ 0 ] + " " + result.TrimEnd( ' ' );
		result = result.TrimEnd( ' ' );
		int Name = AddNode( result.Split( ' ' ) );
		r.isRight = true;
		r.result = Name.ToString();
		return r;
	}
	
	static ReturnMessage 分隔( ReturnMessage r, string[] Cut )
	{
		int TempIndex = Index;
		int TempLength = length;
		r = AssayWord( Cut[ 4 ] );
		if( !r.isRight ) {
			Index = TempIndex;
			length = TempLength;
			return r;
		}
		string result = r.result + " ";
		while( true ) {
			int ttTempIndex = Index;
			int ttTempLength = length;
			r = AssayWord( Cut[ 3 ] );
			if( !r.isRight ) {
				break;
			}
			result += r.result + " ";
			r = AssayWord( Cut[ 4 ] );
			
			//这里修改了,可以处理形如 A.B.3 形式的语法(以前遇到这样的语法则会全部退回);
			if( !r.isRight ) {
				Index = ttTempIndex;
				length = ttTempLength;
				break;
			}
//			if( !r.isRight ) {
//				Index = TempIndex;
//				length = TempLength;
//				return r;
//			}
			result += r.result + " ";
		}
		result = result.TrimEnd( ' ' );
		result = Cut[ 0 ] + " " + result;
		int Name = AddNode( result.Split( ' ' ) );
		r.isRight = true;
		r.result = Name.ToString();
		return r;
	}
	
	static ReturnMessage 优先分隔( ReturnMessage r, string[] Cut )
	{
		r = 分隔( r, Cut );
		if( r.isRight ) {
			DiffusePRI( int.Parse( r.result ) );
		}
		return r;
	}
	
	//优先级分析
	static void DiffusePRI( int Index )
	{
		string[] Cut = NodeSet[ Index ];
		if( Cut.Length == 2 ) {
			return;
		}
	Start:
		//分析结束后应把 "表达式" 换成 "双目运算"
		if( Cut.Length == 4 ) {
			if( NodeSet[ int.Parse( Cut[ 1 ] ) ][ 1 ] != "(" ) {
				Cut[ 0 ] = Node.双目运算符;
			}
			return;
		}
		for( int i = 2; i <= Cut.Length - 2; i += 2 ) {
			int FirstLevel = PRI.GetPRI( WordList.GetWord( int.Parse( Cut[ i ] ) ) );
			if( i == Cut.Length - 2 || 
				PRI.GetPRI( WordList.GetWord( int.Parse( Cut[ i + 2 ] ) ) ) >= FirstLevel ) {
				string node = Node.双目运算符 + " " + Cut[ i - 1 ] + " " + Cut[ i ] + " " + Cut[ i + 1 ];
				int Name = AddNode( node.Split( ' ' ) );
				Cut[ i - 1 ] = "";
				Cut[ i ] = Name.ToString();
				Cut[ i + 1 ] = "";
				string Result = string.Join( " ", Cut ).Replace( "  ", " " ).Trim( ' ' );
				Cut = Result.Split( ' ' );
				NodeSet[ Index ] = Cut;
				goto Start;
			}
		}
	}
	
	//获取一个词的定义
	static string[] GetParse( string Parse )
	{
		for( int i = 0; i < ParseCut.Length; ++i ) {
			if( ParseCut[ i ][ 0 ] == Parse ) {
				return ParseCut[ i ];
			}
		}
		return null;
	}
	
	//静态变量
	public static string[][] NodeSet;	//网络集
	public static int Length
	{
		get{ return length; }
	}
	static int length;			//网络长度
	static string[][] ParseCut;	//语法树列表
	static int[] LinesOfWord;	//真实的行
	static int Index;
	static int FarthestIndex;
	static string ErrorDescribe;
}
}

//	//输出规则语法树
//	public static string ShowRule()
//	{
//		string s = "";
//		for( int i = 0; i < ParseCut.Length; ++i ) {
//			s += string.Join( " ", ParseCut[ i ] ) + "\n";
//		}
//		return s;
//	}
